home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-06-20 | 43.3 KB | 1,388 lines | [TEXT/MWPS] |
- {$N-}
-
- {$IFC UNDEFINED THINK_Pascal}
- {$ELSEC}
- {$I-}
- {$ENDC}
-
-
- { UnmountIt.p }
- { by Jim Luther }
- { Apple Developer Technical Support }
- { Copyright © 1992-1995, Apple Computer Inc. }
- { All rights reserved }
-
- { 03 Mar 93 JML v1.0GM Froze code and released version 1.0. }
- { 03 May 93 JML v1.1d1 Start on 1.1 update to add toggle feature. }
- { 03 May 93 JML v1.1d1 Moved call to GetServerState in kUnmountItem from before }
- { volume selection to after volume selection. }
- { 03 May 93 JML v1.1d1 Added menu handling code and modified resource for }
- { kRestartSharing menu item. }
- { 04 May 93 JML v1.1d2 Added restart handling code to AEOpenHandler and}
- { added auto-quit code to Idle after restart from OpenApp. }
- { 04 May 93 JML v1.1d2 Added code to check for sessions before restart. }
- { 04 May 93 JML v1.1b1 It all worked... declare it beta. It's great to be }
- { the engineer, tester, and designer (grin). }
- { 04 May 93 JML v1.1b1 Oh yeah, I added Brigham's cool color icons. }
- { 24 Mar 94 JML v1.1GM Released (kind of). }
- { 21 May 95 JML v1.2b1 Made changes so UnmountIt compiles with Metrowerks Pascal and }
- { the Universal Interfaces. }
- { 21 May 95 JML v1.2b1 UnmountIt now checks for the AppleShare and for Macintosh }
- { File Sharing 7.6.1 or later. If it finds either, then it alerts }
- { the user and quits. }
-
-
- PROGRAM UnmountIt;
-
- USES
- {$IFC UNDEFINED THINK_Pascal}
- Types, QuickDraw, Events, OSUtils, Files, Devices, DeskBus, DiskInit,{…}
- Disks, Errors, Memory, Retrace, SegLoad, Serial, ShutDown,{…}
- Slots, Sound, Start, Timer, Controls, Windows, TextEdit, Dialogs,{…}
- Fonts, Lists, Menus, Resources, Scrap, ToolUtils, StandardFile, Script,{…}
- Packages, Traps, AppleTalk, PPCToolbox, Processes, EPPC, Notification,{…}
- AppleEvents, GestaltEqu, Balloons, Folders, ServerControlIntf;
- {$ELSEC}
- AppleTalk, PPCToolbox, Processes, EPPC, Notification, AppleEvents, Traps, {…}
- Balloons, Folders, ServerControlIntf;
- {$ENDC}
-
- CONST
- kParam0 = '^0';
- kParam1 = '^1';
- kParam2 = '^2';
- kParam3 = '^3';
-
- kAboutBox = 1000; { AboutBox alert }
- kStopOK = 1001;
- kNoteOK = 1002;
- kCautionCancelOK = 1003;
- kCautionStopContinue = 1004; {not used at this time}
- kCautionCancelSave = 1005; {not used at this time}
-
- kAlertStrings = 1000;
- kBadSystem = 1;
- kNoAppleEvents = 2;
- kAEHandlerInstallError = 3;
- kInfoError = 4;
- kStartupDisk = 5;
- kNonEjectableVol = 6;
- kPeopleConnected = 7;
- kSCShutdownError = 8;
- kStartingStoppingError = 9;
- kFileBusyOnVol = 10;
- kNetTrashFull = 11;
- kPeopleConnectedRestart = 12;
- kIsAppleShareServer = 13;
- kIsNewFileSharingServer = 14;
-
- kStartingStoppingStrings = 1001;
- kStartingStr = 1;
- kOnStr = 2;
- kStoppingStr = 3;
- kOffStr = 4;
-
- kHelp = 2000; { help menu item string and dialog }
-
- kCustomGetVolumeDLOG = 2001;
-
- kResumeMask = 1; { bit of message field for resume vs. suspend }
-
- kMBarID = 128;
-
- kAppleMenu = 128; { the Apple menu }
-
- kFileMenu = 129; { the File menu }
- kUnmountItem = 1;
- kRestartSharing = 2;
- kQuitItem = 4;
-
- TYPE
- volQElemPtr = ^volQElem;
- volQElem = RECORD
- qLink: QElemPtr;
- qType: Integer;
- volumeRefNum: Integer;
- driveNum: Integer;
- volumeName: Str255;
- ejected: Boolean;
- ejectable: Boolean;
- shared: Boolean;
- networkVol: Boolean;
- netTrashVRefNum: Integer;
- netTrashDirID: LongInt;
- netTrashEmpty: Boolean;
- END;
-
- VAR
- gMymenu: Handle; { my menu bar handle }
- gAppleMenuHandle: MenuHandle;
- gFileMenuHandle: MenuHandle;
- gQuit: Boolean;
- gInBackground: Boolean;
- gOurSN: ProcessSerialNumber;
- gHelpItem: Integer; { 0 if no help item }
- gHasAppleEvents: Boolean;
- gHasServerDispatch: Boolean; { TRUE if we can make server control calls }
-
- gServerState: Integer; { the current state of the server - checked right before any unmount }
- gNeedToCheckForSharing: Boolean; { check for sharing at least once per list of volumes }
- gTurnServerBackOn: Boolean; { if TRUE, need to turn server on after unmount/eject }
- gNoSharedVolumes: Boolean; { if TRUE, don't unmount any shared volumes in this list }
- gRestarting: Boolean; { if TRUE, then we're restarting the server }
- gQuitAfterRestart: Boolean; { if TRUE, then quit after restarting the server }
- {••• Need to ignore unmount requests while restarting and ignore restart requests }
- {••• while unmounting. }
- gVolsEnqueued: Boolean; { if TRUE, there are volumes to unmount }
- gVolQHdr: QHdr; { holds list of volumes to unmount/eject }
-
- gFirstAE: AEEventID;
-
- {==============================================================================}
-
- { The NumToolboxTraps, GetTrapType, and TrapAvailable functions are from }
- { Inside Macintosh Volume VI }
-
- {$S Main}
- FUNCTION NumToolboxTraps: Integer;
- BEGIN
- IF NGetTrapAddress(_InitGraf, ToolTrap) = NGetTrapAddress($AA6E, ToolTrap) THEN
- NumToolboxTraps := $200
- ELSE
- NumToolboxTraps := $400;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION GetTrapType (theTrap: Integer): TrapType;
- CONST
- TrapMask = $0800;
- BEGIN
- IF BAND(theTrap, TrapMask) > 0 THEN
- GetTrapType := ToolTrap
- ELSE
- GetTrapType := OSTrap;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION TrapAvailable (theTrap: Integer): Boolean;
- VAR
- tType: TrapType;
- BEGIN
- tType := GetTrapType(theTrap);
- IF tType = ToolTrap THEN
- BEGIN
- theTrap := BAND(theTrap, $07FF);
- IF theTrap >= NumToolboxTraps THEN
- theTrap := _Unimplemented;
- END;
- TrapAvailable := NGetTrapAddress(theTrap, tType) <> NGetTrapAddress(_Unimplemented, ToolTrap)
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION MyCustomGetVolumeFileFilter (myPB: CInfoPBPtr;
- myDataPtr: PTR): BOOLEAN;
- BEGIN
- MyCustomGetVolumeFileFilter := TRUE;
- {list volumes only}
- IF BTst(myPB^.ioFlAttrib, 4) AND (myPB^.ioDrParID = fsRtParID) THEN
- MyCustomGetVolumeFileFilter := FALSE;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION MyCustomGetVolumeHook (item: INTEGER;
- theDialog: DialogPtr;
- myDataPtr: PTR): INTEGER;
- VAR
- dlgPeek: WindowPeek;
- itemType: INTEGER;
- itemToChange: Handle;
- itemBox: Rect;
- buttonTitle: Str255;
- BEGIN
- MyCustomGetVolumeHook := item; {default, except in special cases below}
-
- {CustomGet calls dialog hook for both}
- { main and subsidiary dialog boxes. Check }
- { here that the refCon indicates dialog }
- { record describes main dialog box}
- dlgPeek := WindowPeek(theDialog);
- IF OSType(dlgPeek^.refCon) = sfMainDialogRefCon THEN
- BEGIN
- CASE item OF
- sfHookFirstCall:
- BEGIN
- {set button title and goto desktop}
- buttonTitle := 'Select';
- GetDialogItem(theDialog, sfItemOpenButton, itemType, itemToChange, itemBox);
- SetControlTitle(ControlHandle(itemToChange), buttonTitle);
- MyCustomGetVolumeHook := sfhookGotoDesktop;
- END;
-
- {Map cmd-D to a NullEvent}
- sfhookGotoDesktop:
- MyCustomGetVolumeHook := sfHookNullEvent;
-
- {sfHookRebuildList will work also}
- sfHookChangeSelection:
- MyCustomGetVolumeHook := sfhookGotoDesktop;
-
- {Map cmd-left Arrow to a NullEvent}
- sfHookGotoNextDrive:
- MyCustomGetVolumeHook := sfHookNullEvent;
-
- {Map cmd-right Arrow to a NullEvent}
- sfHookGotoPrevDrive:
- MyCustomGetVolumeHook := sfHookNullEvent;
-
- {return the open button's value}
- sfItemOpenButton, sfHookOpenFolder:
- MyCustomGetVolumeHook := sfItemOpenButton;
- OTHERWISE
- ;
- END;
- END;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE DoCustomGetVolume (VAR volRefNum: Integer);
- VAR
- myCustGetFileReply: StandardFileReply;
- myTypeListNo2: SFTypeList;
- myNumTypes: INTEGER;
- myDlogCoords: Point;
- myModalFilter: ModalFilterYDProcPtr;
- myActiveList: ActivationOrderListPtr;
- myActivateProc: ActivateYDProcPtr;
- BEGIN
- {for first phase of filtering, by file type,}
- { pass files of all types}
- myNumTypes := -1;
- {(-1,-1) for automatic centering of dialog on screen }
- myDlogCoords.h := -1;
- myDlogCoords.v := -1;
- myModalFilter := NIL;
- myActiveList := NIL;
- myActivateProc := NIL;
-
- CustomGetFile(@MyCustomGetVolumeFileFilter, myNumTypes, @myTypeListNo2, myCustGetFileReply, kCustomGetVolumeDLOG, myDlogCoords, @MyCustomGetVolumeHook, myModalFilter, myActiveList, myActivateProc, @myCustGetFileReply);
-
- IF (myCustGetFileReply.sfGood) AND (myCustGetFileReply.sfIsVolume) THEN
- volRefNum := myCustGetFileReply.sfFile.vRefNum
- ELSE
- volRefNum := 0;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- { This function works ONLY with File Sharing file servers released before }
- { File Sharing 7.6.1. DO NOT use it with File Sharing 7.6.1 (or later) or }
- { with AppleShare file servers! }
- FUNCTION numSessions: Integer;
- BEGIN
- { Make sure the file server is up and running }
- IF (LongIntPtr($B50)^ <> 0) AND (LongIntPtr($B50)^ <> -1) THEN
- { it is, so see how many sessions are active }
- numSessions := IntegerPtr(ORD4(LongIntPtr($B50)^) + $10)^
- ELSE { it isn't, so return 0 }
- numSessions := 0;
- END;
-
- {------------------------------------------------------------------------------}
-
- FUNCTION ReleaseFolder (vRefNum: INTEGER; { volume reference number }
- folderType: OSType { always kTrashFolderType }
- ): OSErr;
- INLINE
- $700B, $A823;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION FindTrash (VAR trashVRefNum: Integer;
- VAR trashDirID: LongInt;
- VAR trashEmpty: Boolean): OSErr;
- VAR
- err: OSErr;
- cPB: CInfoPBRec;
- trashName: Str31; { not really needed, but there's that File Sharing bug... }
- BEGIN
- err := FindFolder(trashVRefNum, kTrashFolderType, FALSE, trashVRefNum, trashDirID);
- IF err = noErr THEN
- BEGIN
- cPB.ioNamePtr := @trashName;
- cPB.ioVRefNum := trashVRefNum;
- cPB.ioDirID := trashDirID;
- cPB.ioFDirIndex := -1;
- err := PBGetCatInfoSync(@cPB);
- IF err = noErr THEN
- BEGIN
- trashEmpty := cPB.ioDrNmFls = 0;
- END;
- END
- ELSE IF (err = fnfErr) THEN
- BEGIN
- trashVRefNum := 0;
- trashDirID := 0;
- trashEmpty := true;
- err := noErr;
- END;
- FindTrash := err;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION GetVolumeInfo (volInfoPtr: volQElemPtr): OSErr;
- VAR
- volParmsInfoBuffer: GetVolParmsInfoBuffer;
- drvQElem: DrvQElPtr;
- pb: HParamBLockRec;
- err: OSErr;
- BEGIN
- pb.ioNamePtr := @volInfoPtr^.volumeName;
- pb.ioVRefNum := volInfoPtr^.volumeRefNum;
- pb.ioVolIndex := 0;
- err := PBHGetVInfoSync(@pb);
- IF (err = noErr) THEN
- BEGIN
- volInfoPtr^.driveNum := pb.ioVDrvInfo;
- { is it ejected? }
- volInfoPtr^.ejected := (pb.ioVDrvInfo = 0) AND (pb.ioVDRefNum > 0);
-
- drvQElem := DrvQElPtr(GetDrvQHdr^.qHead); { get the first drive queue entry }
- { find the drive queue entry for this volume }
- WHILE (drvQElem <> NIL) & (drvQElem^.dQDrive <> pb.ioVDrvInfo) DO
- drvQElem := DrvQElPtr(drvQElem^.qLink);
- { is it ejectable? }
- volInfoPtr^.ejectable := (drvQElem <> NIL) & (Ptr(ORD4(drvQElem) - 3)^ <> 8);
- END;
-
- pb.ioNamePtr := NIL;
- pb.ioVRefNum := volInfoPtr^.volumeRefNum;
- pb.ioBuffer := @volParmsInfoBuffer;
- pb.ioReqCount := sizeof(GetVolParmsInfoBuffer);
- { Since PBHGetVolParms is always available under System 7, any errors are real errors }
- err := PBHGetVolParmsSync(@pb);
- { is it shared? }
- volInfoPtr^.shared := (err = noErr) & BTST(volParmsInfoBuffer.vMAttrib, bHasPersonalAccessPrivileges);
- volInfoPtr^.networkVol := volParmsInfoBuffer.vMServerAdr <> 0;
- IF volInfoPtr^.networkVol THEN
- BEGIN
- WITH volInfoPtr^ DO
- BEGIN
- netTrashVRefNum := volumeRefNum;
- err := FindTrash(netTrashVRefNum, netTrashDirID, netTrashEmpty);
- END;
- END;
-
- GetVolumeInfo := err; { return any errors }
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION ShutDownTheServer: OSErr;
- VAR
- scErr: OSErr;
- scPB: SCParamBlockRec;
- pdsName: Str255;
- hPB: HParamBlockRec;
- BEGIN
- scPB.disconnectPB.scCode := SCShutDown;
- scPB.disconnectPB.scNumMinutes := 0; { shut down NOW! }
- scPB.disconnectPB.scFlags := 0;
- scPB.disconnectPB.scMessagePtr := NIL;
- scErr := SyncServerDispatch(@scPB);
- ShutDownTheServer := scErr;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE StartTheServer;
- VAR
- scPB: SCParamBlockRec;
- BEGIN
- scPB.startPB.scCode := SCStartServer;
- scPB.startPB.scStartSelect := kCurInstalled;
- scPB.startPB.scEventSelect := kFinderExtn;
- IF SyncServerDispatch(@scPB) <> noErr THEN
- ; { who cares }
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE AddToVolQueue (myFSS: FSSpec);
- VAR
- foundVRefNum: Integer;
- foundDirID: LongInt;
- volInfoPtr: volQElemPtr;
- itemHit: Integer;
- paramPos: Integer;
- alertString, paramStr0, paramStr1: Str255;
- BEGIN
- { filter out folders }
- IF myFSS.parID <> fsRtParID THEN
- Exit(AddToVolQueue);
-
- { filter out the boot volume }
- IF FindFolder(kOnSystemDisk, kSystemFolderType, FALSE, foundVRefNum, foundDirID) = noErr THEN
- BEGIN
- IF foundVRefNum = myFSS.vRefNum THEN
- BEGIN
- { Tell user “The startup disk cannot be removed from the desktop, }
- { because it contains the active system software.”}
- GetIndString(alertString, kAlertStrings, kStartupDisk);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- Exit(AddToVolQueue);
- END;
- END
- ELSE
- Exit(AddToVolQueue);
-
- { It's passed enough tests to create a queue element for it. }
- volInfoPtr := volQElemPtr(NewPtr(LongInt(sizeof(volQElem))));
- IF volInfoPtr = NIL THEN
- Exit(AddToVolQueue); { this shouldn't happen, but… }
-
- { add the volume reference number to the queue element }
- volInfoPtr^.volumeRefNum := myFSS.vRefNum;
-
- { and find out everything about this volume }
- IF GetVolumeInfo(volInfoPtr) <> noErr THEN
- BEGIN { oops, something was BAAAAAAD so skip this one }
- GetIndString(alertString, kAlertStrings, kInfoError);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- DisposePtr(Ptr(volInfoPtr)); { give back the memory }
- Exit(AddToVolQueue);
- END;
-
- { check net-trash on network volumes }
- IF (volInfoPtr^.networkVol) AND (NOT volInfoPtr^.netTrashEmpty) THEN
- BEGIN
- { “The shared disk “^0” could not be put away, because some of }
- { its items have been moved to the Trash. Do you want to delete }
- { those items and then put away the disk?”}
- { Cancel: then don't do it}
- { OK: continue }
- GetIndString(alertString, kAlertStrings, kNetTrashFull);
- paramPos := pos(kParam0, alertString);
- delete(alertString, paramPos, 2);
- insert(volInfoPtr^.volumeName, alertString, paramPos);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kCautionCancelOK, NIL);
- IF itemHit = cancel THEN
- BEGIN
- DisposePtr(Ptr(volInfoPtr)); { give back the memory }
- Exit(AddToVolQueue);
- END;
- END;
-
- IF (NOT volInfoPtr^.ejectable) AND (NOT volInfoPtr^.networkVol) THEN
- BEGIN
- { “Are you sure you want to remove the disk “^0” from the desktop? }
- { It will reappear on the desktop when the Macintosh is restarted.”}
- { Cancel: then don't do it}
- { OK: continue }
- GetIndString(alertString, kAlertStrings, kNonEjectableVol);
- paramPos := pos(kParam0, alertString);
- delete(alertString, paramPos, 2);
- insert(volInfoPtr^.volumeName, alertString, paramPos);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kCautionCancelOK, NIL);
- IF itemHit = cancel THEN
- BEGIN
- DisposePtr(Ptr(volInfoPtr)); { give back the memory }
- Exit(AddToVolQueue);
- END;
- END;
-
- IF volInfoPtr^.shared THEN
- BEGIN
- IF gNeedToCheckForSharing THEN
- BEGIN
- gNeedToCheckForSharing := FALSE; { don't need to ask after 1st shared volume }
- CASE gServerState OF
- SCPSRunning:
- BEGIN
- IF (numSessions > 0) THEN
- BEGIN
- { “There are people connected to this Macintosh. }
- { Do you want to disconnect them and unmount the }
- { shared volume(s) anyway?”}
- { Yes: gNoSharedVolumes := FALSE }
- { No: gNoSharedVolumes := TRUE }
- GetIndString(alertString, kAlertStrings, kPeopleConnected);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kCautionCancelOK, NIL);
- gNoSharedVolumes := itemHit = cancel;
- IF NOT gNoSharedVolumes THEN
- IF ShutDownTheServer = noErr THEN
- gTurnServerBackOn := TRUE { we'll turn it back on later }
- ELSE
- BEGIN
- DisposePtr(Ptr(volInfoPtr)); { give back the memory }
- Exit(AddToVolQueue);
- END;
- END
- ELSE
- { nobody is on, so shut down the server }
- IF ShutDownTheServer = noErr THEN
- gTurnServerBackOn := TRUE { we'll turn it back on later }
- ELSE
- BEGIN
- GetIndString(alertString, kAlertStrings, kSCShutdownError);
- paramPos := pos(kParam0, alertString);
- delete(alertString, paramPos, 2);
- insert(volInfoPtr^.volumeName, alertString, paramPos);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- { we couldn't shut down the server for some }
- { unknown or unexpected reason}
- DisposePtr(Ptr(volInfoPtr)); { give back the memory }
- Exit(AddToVolQueue);
- END;
- END;
- SCPSJustDisabled, SCPSDisabledwErr:
- BEGIN
- gNoSharedVolumes := FALSE;
- {do nothing!}
- END;
- SCPSStartingUp:
- BEGIN
- { Give this dialog and don't unmount shared volumes: }
- {“File sharing is starting up, please wait until the Sharing Setup }
- {control panel indicates it is on, and then try again.” OK }
- GetIndString(alertString, kAlertStrings, kStartingStoppingError);
-
- GetIndString(paramStr0, kStartingStoppingStrings, kStartingStr);
- paramPos := pos(kParam0, alertString);
- delete(alertString, paramPos, 2);
- insert(paramStr0, alertString, paramPos);
-
- GetIndString(paramStr1, kStartingStoppingStrings, kOnStr);
- paramPos := pos(kParam1, alertString);
- delete(alertString, paramPos, 2);
- insert(paramStr1, alertString, paramPos);
-
- ParamText(alertString, '', '', '');
- itemHit := Alert(kNoteOK, NIL);
- gNoSharedVolumes := TRUE;
- END;
- SCPSSleeping:
- BEGIN
- { This is AppleShare 3.0 which already supports unmounting on the fly.}
- {We shouldn't get this since we don't run with anything but file sharing}
- gNoSharedVolumes := FALSE;
- END;
- OTHERWISE
- BEGIN
- { Give this dialog (maybe this isn’t needed… if not, we’d have to cancel}
- {the current shutdown and then shutdown(0) ourselves) and then bail: }
- {“File sharing is shutting down, please wait until the Sharing Setup }
- {control panel indicates it is off, and then try again.” OK }
- GetIndString(alertString, kAlertStrings, kStartingStoppingError);
-
- GetIndString(paramStr0, kStartingStoppingStrings, kStoppingStr);
- paramPos := pos(kParam0, alertString);
- delete(alertString, paramPos, 2);
- insert(paramStr0, alertString, paramPos);
-
- GetIndString(paramStr1, kStartingStoppingStrings, kOffStr);
- paramPos := pos(kParam1, alertString);
- delete(alertString, paramPos, 2);
- insert(paramStr1, alertString, paramPos);
-
- ParamText(alertString, '', '', '');
- itemHit := Alert(kNoteOK, NIL);
- gNoSharedVolumes := TRUE;
- END;
- END;
- END;
- { You didn't want to kick users off? OK, no shared volumes then }
- { (dialog already told user). }
- IF gNoSharedVolumes THEN
- BEGIN
- DisposePtr(Ptr(volInfoPtr)); { give back the memory }
- Exit(AddToVolQueue);
- END;
- END;
-
- { Hey, this volume is really going to make it into the queue }
- Enqueue(QElemPtr(volInfoPtr), @gVolQHdr);
- gVolsEnqueued := TRUE;
-
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION DeleteDirectory (vRefNum: Integer;
- dirID: LongInt): OSErr;
- CONST
- fsDirFlgBit = 4;
- VAR
- err: OSErr;
- itemName: Str63;
- hPB: HParamBlockRec;
-
- PROCEDURE DeleteLevel (dirToDelete: LongInt);
- { Delete everything at and below this level. }
- { The recursion stops if there's a non-recoverable error. }
- VAR
- savedDir: LongInt;
- BEGIN
- REPEAT
- hPB.ioNamePtr := @itemName; { prepare to delete directory }
- hPB.ioFDirIndex := 1; { get first item (every time) }
- hPB.ioDirID := dirToDelete; { in this directory }
- err := PBGetCatInfoSync(@hPB);
- IF err = noErr THEN { did we find something? }
- BEGIN
- savedDir := dirToDelete;
- IF BTST(hPB.ioFlAttrib, fsDirFlgBit) THEN { if directory }
- BEGIN
- savedDir := hPB.ioDirID;
- DeleteLevel(hPB.ioDirID); { delete its contents }
- hPB.ioNamePtr := NIL; { prepare to delete directory }
- END;
- IF err = noErr THEN
- BEGIN { if no errors }
- hPB.ioDirID := savedDir; { restore parent dirID }
- err := PBHDeleteSync(@hPB); { delete this item }
- IF err = fLckdErr THEN
- BEGIN { if item was locked }
- err := PBHRstFLockSync(@hPB); { unlock it }
- err := PBHDeleteSync(@hPB); { and try again }
- END;
- END;
- END;
- UNTIL (err <> noErr); { keep going if no errors }
- IF err = fnfErr THEN { there's nothing left at this level }
- err := noErr; { that's OK, so pass back noErr }
- END; { DeleteLevel }
-
- BEGIN { DeleteDirectory }
- hPB.ioVRefNum := vRefNum;
- DeleteLevel(dirID);
- IF err = noErr THEN
- BEGIN { everything below was deleted }
- hPB.ioNamePtr := NIL;
- hPB.ioDirID := dirID;
- err := PBHDeleteSync(@hPB); { so delete dirID }
- IF err = fLckdErr THEN
- BEGIN { if item was locked }
- err := PBHRstFLockSync(@hPB); { unlock it }
- err := PBHDeleteSync(@hPB); { and try again }
- END;
- END;
- DeleteDirectory := err;
- END; { DeleteDirectory }
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE UnmountAndEjectVolQueue;
- VAR
- volInfoPtr: volQElemPtr;
- err: OSErr;
- pb: HParamBlockRec;
- itemHit: Integer;
- alertString: Str255;
- paramPos: Integer;
- BEGIN
- WHILE gVolQHdr.qHead <> NIL DO
- BEGIN
- volInfoPtr := volQElemPtr(gVolQHdr.qHead);
- IF Dequeue(QElemPtr(volInfoPtr), @gVolQHdr) <> noErr THEN
- ; {we should never get an error, since this is the only place we dequeue}
-
- { take out the net trash }
- IF (volInfoPtr^.networkVol) AND (NOT volInfoPtr^.netTrashEmpty) THEN
- BEGIN
- err := DeleteDirectory(volInfoPtr^.volumeRefNum, volInfoPtr^.netTrashDirID);
- IF err = noErr THEN
- err := ReleaseFolder(volInfoPtr^.volumeRefNum, kTrashFolderType);
- END;
-
- { unmount it }
- pb.ioNamePtr := NIL;
- pb.ioVRefNum := volInfoPtr^.volumeRefNum;
- err := PBUnmountVol(@pb);
- IF err = noErr THEN
- BEGIN
- IF volInfoPtr^.ejectable AND (NOT volInfoPtr^.ejected) THEN
- BEGIN
- { and eject it }
- pb.ioNamePtr := NIL;
- pb.ioVRefNum := volInfoPtr^.driveNum;
- err := PBEject(@pb);
- END;
- END
- ELSE
- BEGIN
- GetIndString(alertString, kAlertStrings, kFileBusyOnVol);
- paramPos := pos(kParam0, alertString);
- delete(alertString, paramPos, 2);
- insert(volInfoPtr^.volumeName, alertString, paramPos);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- END;
- DisposePtr(Ptr(volInfoPtr));
- END;
- gVolsEnqueued := FALSE;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE GetServerState;
- VAR
- index: LongInt;
- scErr: OSErr;
- scPB: SCParamBlockRec;
- BEGIN
- { get current server state }
- IF gHasServerDispatch THEN
- BEGIN
- gNeedToCheckForSharing := TRUE;
-
- scPB.pollServerPB.scCode := SCPollServer;
- IF SyncServerDispatch(@scPB) = noErr THEN
- gServerState := scPB.pollServerPB.scServerState
- ELSE
- gServerState := SCPSDisabledwErr; {something bad is going on,}
- {but we should be able to continue.}
- END;
- gTurnServerBackOn := FALSE;
- gNoSharedVolumes := FALSE;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE DoDiskEvents (dinfo: LongInt);
- { DoDiskEvents just checks the error code from the disk mount, }
- { and puts up the 'Format' dialog (through DIBadMount) if need be }
- { You can do much more here if you care about what disks are }
- { in the drive }
- VAR
- hival, loval: Integer;
- tommy: Integer;
- fredpoint: Point;
- BEGIN
- fredpoint.v := 40;
- fredpoint.h := 40;
- { hi word is error code, lo word is drive number }
- hival := HiWord(dinfo);
- loval := LoWord(dinfo);
- IF hival <> noErr THEN { something happened }
- tommy := DIBadMount(fredpoint, dinfo);
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE ShowHelpDialog;
- { This is my sample help dialog. It doesn't do anything. Expand as you need. }
- VAR
- tdial: DialogPtr;
- itemHit: Integer;
- BEGIN
- tdial := GetNewDialog(kHelp, NIL, WindowPtr(-1));
- REPEAT
- ModalDialog(NIL, itemhit);
- UNTIL itemhit = 1;
- DisposeDialog(tdial);
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE DrawMain (drawit: WindowPtr);
- { draws my window. Pretty simple }
- BEGIN
- BeginUpdate(drawIt);
- SetPort(drawIt);
-
- EndUpdate(drawIt);
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE DoSelected (val: LongInt);
- { my menu action taker }
- VAR
- hival, loval: Integer;
- qq: Integer;
- DAname: Str255;
- myFSS: FSSpec;
- itemHit: Integer;
- alertString, paramStr0, paramStr1: Str255;
- BEGIN
- loval := LoWord(val);
- hival := HiWord(val);
-
- CASE hival OF { switch off the menu number selected }
- kAppleMenu:
- BEGIN
- IF loval <> 1 THEN {if this was not About, it's a DA }
- BEGIN
- GetMenuItemText(gAppleMenuHandle, loval, DAname);
- qq := OpenDeskAcc(DAname);
- END
- ELSE
- qq := Alert(kAboutBox, NIL); { do about box }
- END;
- kFileMenu:
- BEGIN
- CASE loval OF
- kUnmountItem:
- BEGIN
- DoCustomGetVolume(myFSS.vRefNum);
- IF myFSS.vRefNum <> 0 THEN
- BEGIN
- GetServerState; { see what server is up to }
- myFSS.parID := fsRtParID;
- myFSS.name := '';
- AddToVolQueue(myFSS);
- END;
- END;
- kRestartSharing:
- BEGIN
- IF (numSessions > 0) THEN
- BEGIN
- { “There are people connected to this Macintosh. }
- { Do you want to disconnect them and restart }
- { file sharing anyway?”}
- GetIndString(alertString, kAlertStrings, kPeopleConnectedRestart);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kCautionCancelOK, NIL);
- IF NOT (itemHit = cancel) THEN
- IF ShutDownTheServer = noErr THEN
- gRestarting := TRUE; { we'll turn it back on later }
- END
- ELSE IF ShutDownTheServer = noErr THEN
- gRestarting := TRUE;{ we'll turn it back on later }
- END;
- kQuitItem:
- gQuit := TRUE; { only item }
- OTHERWISE
- ;
- END; { case loval }
- END;
- kHMHelpMenuID: { Defined in Balloons }
- { I only care about this item. If anything else is returned here, I don't know what }
- { it is, so I leave it alone. Remember, the Help Manager chapter says that }
- { Apple reserves the right to add and change things in the Help menu }
- BEGIN
- IF loval = gHelpItem THEN
- ShowHelpDialog;
- END;
- OTHERWISE
- ;
- END; { CASE hival }
- HiliteMenu(0);
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION AEOpenHandler (messagein: AppleEvent;
- reply: AppleEvent;
- refIn: LongInt): OSErr;
- { This is the standard Open Application event. }
- VAR
- theKeys: KeyMap;
- alertString: Str255;
- itemHit: Integer;
- BEGIN
- IF (gFirstAE <> kAEPrintDocuments) AND (gFirstAE <> kAEOpenDocuments) THEN
- BEGIN
- gFirstAE := kAEOpenApplication;
-
- { if control key is down, then restart and quit }
- GetKeys(theKeys);
- IF theKeys[$3b] THEN
- BEGIN
- GetServerState; { see what the server is up to }
- IF (gServerState = SCPSRunning) THEN
- BEGIN
- IF (numSessions > 0) THEN
- BEGIN
- { “There are people connected to this Macintosh. }
- { Do you want to disconnect them and restart }
- { file sharing anyway?”}
- GetIndString(alertString, kAlertStrings, kPeopleConnectedRestart);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kCautionCancelOK, NIL);
- IF NOT (itemHit = cancel) THEN
- IF ShutDownTheServer = noErr THEN
- BEGIN
- gRestarting := TRUE; { we'll turn it back on later }
- gQuitAfterRestart := TRUE;
- END;
- END
- ELSE IF ShutDownTheServer = noErr THEN
- BEGIN
- gRestarting := TRUE;{ we'll turn it back on later }
- gQuitAfterRestart := TRUE;
- END;
- END;
- END;
- END;
-
- AEOpenHandler := noErr;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION AEOpenDocHandler (theAppleEvent, reply: AppleEvent;
- handlerRefcon: LongInt): OSErr;
- { Open Doc, opens our documents. Remember, this can happen at application start AND }
- { anytime else. If your app is up and running and the user goes to the desktop, hilites one }
- { of your files, and double-clicks or selects Open from the Finder File menu this event }
- { handler will get called. Which means you don't do any initialization of globals here, or }
- { anything else except open the doc. }
- { SO-- Do NOT assume that you are at app start time in this }
- { routine, or bad things will surely happen to you. }
- VAR
- myFSS: FSSpec;
- docList: AEDescList;
- myErr: OSErr;
- index, itemsInList: LongInt;
- actualSize: Size;
- keywd: AEKeyword;
- returnedType: DescType;
- BEGIN
- IF (gFirstAE <> kAEOpenApplication) AND (gFirstAE <> kAEPrintDocuments) THEN
- gFirstAE := kAEOpenDocuments;
-
- {get the direct parameter--a descriptor list--and put it into docList}
- myErr := AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, docList);
- IF myErr <> noErr THEN
- BEGIN
- AEOpenDocHandler := myErr;
- Exit(AEOpenDocHandler);
- END;
-
- {count the number of descriptor records in the list}
- myErr := AECountItems(docList, itemsInList);
- IF myErr <> noErr THEN
- BEGIN
- AEOpenDocHandler := myErr;
- Exit(AEOpenDocHandler);
- END;
-
- IF itemsInList > 0 THEN
- BEGIN
- GetServerState; { see what the server is up to }
-
- { now get each descriptor record from the list, coerce the returned }
- { data to an FSSpec record, and unmount associated}
- FOR index := 1 TO itemsInList DO
- BEGIN
- myErr := AEGetNthPtr(docList, index, typeFSS, keywd, returnedType, @myFSS, Sizeof(myFSS), actualSize);
- IF myErr <> noErr THEN
- Cycle;
- AddToVolQueue(myFSS);
- END;
- END;
- myErr := AEDisposeDesc(docList);
- AEOpenDocHandler := myErr;
-
- { Quit if this was dragNdrop launch, but no volumes are going to be unmounted. }
- IF (gFirstAE = kAEOpenDocuments) AND (NOT gVolsEnqueued) THEN
- gQuit := TRUE;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION AEPrintHandler (messagein: AppleEvent;
- reply: AppleEvent;
- refIn: LongInt): OSErr;
- BEGIN
- { no printing handler in yet, so we'll ignore this }
- { the operation is functionally identical to the ODOC event, with the addition }
- { of calling your print routine. }
- { we of course don't do anything here }
- IF (gFirstAE <> kAEOpenApplication) AND (gFirstAE <> kAEOpenDocuments) THEN
- gFirstAE := kAEPrintDocuments;
-
- AEPrintHandler := errAEEventNotHandled; { we have no docs, so no pdoc events should come to us }
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- FUNCTION AEQuitHandler (messagein: AppleEvent;
- reply: AppleEvent;
- refIn: LongInt): OSErr;
- { Standard Quit event handler, to handle a Quit event from the Finder, for example. }
- BEGIN
- { prepQuit sets the Stop flag for us. It does _NOT_ quit, you }
- { should NEVER quit from an AppleEvent handler. Calling }
- { ExitToShell here would blow things up }
- gQuit := TRUE;
- AEQuitHandler := noErr;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE DoHighLevel (AERecord: EventRecord);
- { I'm not doing error handling in this sample for clarities sake, you should. }
- { Hah, easy for me to say, huh? }
- VAR
- err: OSErr;
- BEGIN
- err := AEProcessAppleEvent(AERecord);
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE Idling;
- BEGIN
- IF gVolsEnqueued THEN
- BEGIN
- IF gTurnServerBackOn THEN
- BEGIN
- { if the server was on, then we have to wait for the file service }
- { to shut down before we can unmount the volumes }
- { (because something was shared) }
- IF (LongIntPtr($b50)^ = 0) OR (LongIntPtr($b50)^ = -1) THEN
- BEGIN
- UnmountAndEjectVolQueue;
- StartTheServer;
- IF gFirstAE = kAEOpenDocuments THEN
- gQuit := TRUE;
- END;
- END
- ELSE
- BEGIN
- UnmountAndEjectVolQueue;
- IF gFirstAE = kAEOpenDocuments THEN
- gQuit := TRUE;
- END;
- END;
- IF gRestarting THEN
- BEGIN
- IF (LongIntPtr($b50)^ = 0) OR (LongIntPtr($b50)^ = -1) THEN
- BEGIN
- StartTheServer;
- gRestarting := FALSE;
- IF gQuitAfterRestart THEN
- gQuit := TRUE;
- END;
- END;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Main}
- PROCEDURE DoEventLoop;
- { yeah, first I took it out of the main program and now I think I'll split it up }
- { into smaller pieces. However, it'll still be in the same source code file }
- { (don't you hate having to look all over hell for code) }
- VAR
- twindow: WindowPtr;
- evtRecord: EventRecord;
- BEGIN
- REPEAT
- IF WaitNextEvent(everyEvent, evtRecord, 30, NIL) THEN
- CASE evtRecord.what OF
- mouseDown: { first, see where the hit was }
- BEGIN
- CASE FindWindow(Point(evtRecord.where), twindow) OF
- inDesk: { if they hit in desk, then the process manager }
- { will switch us out, we don't need to do anything }
- BEGIN
- END;
- inMenuBar:
- BEGIN
- IF (gRestarting OR gVolsEnqueued) THEN
- BEGIN
- DisableItem(gFileMenuHandle, kUnmountItem);
- DisableItem(gFileMenuHandle, kRestartSharing);
- END
- ELSE
- BEGIN
- EnableItem(gFileMenuHandle, kUnmountItem);
- GetServerState; { see what the server is up to }
- IF (gServerState = SCPSRunning) THEN
- EnableItem(gFileMenuHandle, kRestartSharing)
- ELSE
- DisableItem(gFileMenuHandle, kRestartSharing);
- END;
- DoSelected(MenuSelect(evtRecord.where));
- END;
- inSysWindow: { pass to the system }
- BEGIN
- SystemClick(evtRecord, twindow);
- END;
- inContent: { handle content and control clicks here }
- BEGIN
- END;
- inDrag:
- BEGIN
- IF twindow = FrontWindow THEN
- DragWindow(twindow, Point(evtRecord.where), qd.screenBits.bounds);
- END;
- inGrow: { Call GrowWindow here if you have a grow box }
- BEGIN
- END;
- inGoAway: { Click in Close box }
- BEGIN
- END;
- OTHERWISE
- ;
- END; { CASE FindWindow(evtRecord.message, twindow) }
- END;
- mouseUp:
- ; { don't care }
- keyDown, { same action for key or auto key }
- autoKey:
- IF BAND(evtRecord.modifiers, cmdKey) <> 0 THEN
- DoSelected(MenuKey(CHAR(BAND(evtRecord.message, charCodeMask))));
- keyUp:
- ; { don't care }
- updateEvt:
- { draw whatever window needs an update }
- DrawMain(WindowPtr(evtRecord.message));
- diskEvt:
- { I don't do anything special for disk events, this just passes them }
- { to a function that checks for an error on the mount }
- DoDiskEvents(evtRecord.message);
- activateEvt:
- IF BAND(evtRecord.modifiers, activeFlag) <> 0 THEN
- DrawMain(WindowPtr(evtRecord.message));
- osEvt:
- CASE BSR(evtRecord.message, 24) OF { high byte of message }
- mouseMovedMessage:
- ; { don't care }
- suspendResumeMessage: {suspend/resume is also an activate/deactivate }
- gInBackground := BAND(evtRecord.message, resumeFlag) = 0;
- OTHERWISE
- ;
- END;
- kHighLevelEvent:
- DoHighLevel(evtRecord);
- OTHERWISE
- ;
- END { CASE evtRecord.what }
- ELSE
- Idling; { do my idle stuff }
- UNTIL gQuit = TRUE;
- END; { DoEventLoop }
-
- {------------------------------------------------------------------------------}
-
- {$S Initialize}
- PROCEDURE WhatWeGot;
- CONST
- kNewFileSharingVersion = $3e; { File Sharing 4.0's version number }
- VAR
- vers: LongInt;
- err: OSErr;
- aLong: LongInt;
- scPB: SCParamBlockRec;
- itemHit: Integer;
- alertString: Str255;
- BEGIN
- { Check system version }
- vers := 0;
- err := Gestalt(gestaltSystemVersion, vers);
- IF LoWord(vers) < $0700 THEN
- BEGIN
- GetIndString(alertString, kAlertStrings, kBadSystem);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- ExitToShell;
- END;
-
- { Check this machine for AppleEvents. }
- { If they are not here (i.e., not 7.0) then we exit }
- gHasAppleEvents := Gestalt(gestaltAppleEventsAttr, aLong) = noErr;
- IF NOT gHasAppleEvents THEN
- BEGIN
- GetIndString(alertString, kAlertStrings, kNoAppleEvents);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- ExitToShell;
- END;
-
- { Check this machine for a file server. }
- { If no file server, then exit. }
- gHasServerDispatch := TrapAvailable(ServerDispatch);
-
- IF gHasServerDispatch THEN
- BEGIN
- { get server version.}
- scPB.versionPB.scCode := SCServerVersion;
- scPB.versionPB.scExtNamePtr := NIL;
- {pretend server isn't there if error or the server is not file sharing}
- { v1.2 - or we have the new File Sharing which lets you unmount volumes without }
- { killing the server first. }
- err := SyncServerDispatch(@scPB);
- IF (err <> noErr) OR
- (scPB.versionPB.scServerType <> MFSType) OR
- (scPB.versionPB.scServerVersion >= kNewFileSharingVersion) THEN
- gHasServerDispatch := FALSE;
-
- IF (err = noErr) AND (scPB.versionPB.scServerType <> MFSType) THEN
- BEGIN
- GetIndString(alertString, kAlertStrings, kIsAppleShareServer);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- ExitToShell;
- END;
-
- IF (err = noErr) AND (scPB.versionPB.scServerVersion >= kNewFileSharingVersion) THEN
- BEGIN
- GetIndString(alertString, kAlertStrings, kIsNewFileSharingServer);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- ExitToShell;
- END;
- END;
-
- err := GetCurrentProcess(gOurSN); { Get our process serial number for later use, if needed }
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Initialize}
- PROCEDURE DoSetupMenus;
- VAR
- helpHandle: MenuHandle;
- helpString: StringHandle;
- count: Integer;
- BEGIN
- gMymenu := GetNewMBar(kMBarID);
- SetMenuBar(gMymenu);
- gAppleMenuHandle := GetMenuHandle(kAppleMenu);
- gFileMenuHandle := GetMenuHandle(kFileMenu);
- AppendResMenu(gAppleMenuHandle, 'DRVR');
-
- { now install my Help menu item in the Help Manager's menu }
- IF HMGetHelpMenuHandle(helpHandle) = noErr THEN { Get the Help menu handle }
- BEGIN
- count := CountMItems(helpHandle); { How many items are there? }
- helpString := GetString(kHelp);{ get my help menu item string }
- DetachResource(Handle(helpString)); { detach it }
- HNoPurge(Handle(helpString));
- MoveHHi(Handle(helpString));
- HLock(Handle(helpString));
- InsertMenuItem(helpHandle, helpString^^, count + 1); { insert my item in the Help menu }
- gHelpItem := CountMItems(helpHandle); { The number of the item }
- END
- ELSE
- gHelpItem := 0; { error - set it to something that we'll never see }
-
- DrawMenuBar;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Initialize}
- PROCEDURE InitAEStuff;
- VAR
- alertString: Str255;
- itemHit: Integer;
- BEGIN
- { The following series of calls installs all our AppleEvent Handlers. }
- { These handlers are added to the application event handler list that }
- { the AppleEvent manager maintains. So, whenever an AppleEvent happens }
- { and we call AEProcessEvent, the AppleEvent manager will check our }
- { list of handlers and dispatch to it if there is one. }
- IF (AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, @AEOpenHandler, 0, false) <> noErr) | (AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, @AEOpenDocHandler, 0, false) <> noErr) | (AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, @AEQuitHandler, 0, false) <> noErr) | (AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, @AEPrintHandler, 0, false) <> noErr) THEN { <- the short-circuit OR lets us bail on first error }
- BEGIN
- GetIndString(alertString, kAlertStrings, kAEHandlerInstallError);
- ParamText(alertString, '', '', '');
- itemHit := Alert(kStopOK, NIL);
- ExitToShell;
- END;
- END;
-
- {------------------------------------------------------------------------------}
-
- {$S Initialize}
- PROCEDURE InitializeApp;
- BEGIN
- MaxApplZone;
- { MoreMasters go here if you need'm }
- InitGraf(@qd.thePort);
- InitFonts;
- InitWindows;
- InitMenus;
- TEInit;
- InitDialogs(NIL);
- InitCursor;
-
- WhatWeGot; { make sure everything we need is available }
-
- InitAEStuff;
-
- DoSetupMenus; { set up my menus }
-
- { Initialize the rest of my globals that aren't initialized elsewhere! }
-
- gQuit := FALSE;
- gInBackground := FALSE;
-
- IF NOT gHasServerDispatch THEN
- gServerState := SCPSJustDisabled; { server isn't installed - same as disabled }
- gNeedToCheckForSharing := FALSE;
- gTurnServerBackOn := FALSE;
- gNoSharedVolumes := TRUE;
- gRestarting := FALSE;
- gQuitAfterRestart := FALSE;
-
- { clear the volume queue }
- gVolsEnqueued := FALSE;
- gVolQHdr.QHead := NIL;
- gVolQHdr.QTail := NIL;
-
- { It was like this }
- { gFirstAE := Concat(chr(0), chr(0), chr(0), chr(0)); } { zero it out }
- gFirstAE[1] := chr(0); { zero it out }
- gFirstAE[2] := chr(0); { zero it out }
- gFirstAE[3] := chr(0); { zero it out }
- gFirstAE[4] := chr(0); { zero it out }
- END;
-
- {------------------------------------------------------------------------------}
-
- { PROCEDURE _DataInit;}
- { External;}
- { this is the application initialization code }
-
- {==============================================================================}
-
- {$S Main}
- BEGIN
- { UnloadSeg(@_DataInit);}
- { throw out the setup code }
- InitializeApp;
- { UnloadSeg(@InitializeApp); }
- { get rid of my initialization code }
- DoEventLoop;
- END.